import socketserver
import socket
import json
import numpy as np
from lslSender import LSLSender
# import threading
# import array
import struct

PORT = 6002
mLSL = LSLSender('dummy')

class DATAPKG(object):
    """docstring for DATAPKG"""
    def __init__(self, arg):
        super(DATAPKG, self).__init__()
        self.arg = arg
        # self.pkg_arr = None
        self.last_pkn = 0
        self.CH_NUM = 4
        self.PKG_DATA_OFFSET = 4

    def new_data_pkg_binary(self,arr):
        # do not deal with the packet loss
        # self.pkg_arr = arr

        if (len(arr))!=812:
            print('something wrong, len is :'+str(len(arr)))
            return

        # arr_int = np.zeros((10*3*9))
        for i in range(10):
            offset_pkg = i*3*9*3

            arr_int =  np.zeros((3*8),dtype = np.int32) # one sample point,with 24 channels 

            for chip_n in range(3):
                offset_pkg_chip = offset_pkg + chip_n*3*9
                for ch in range(1,9): # ignore the 24 status bits
                    tmp = bytearray(4)
                    for t in range(3):
                        tmp[t+1] = arr[offset_pkg_chip+ch*3+t]
                    if tmp[1] & 0x80:
                        tmp[0] = 0xFF
                    else:
                        tmp[0] = 0x00

                    arr_int[chip_n*8+ch-1] = struct.unpack('>i', tmp)[0]
                    # arr_int[i*27+chip_n*9+ch] = struct.unpack('>i', tmp)[0]

            mLSL.send_eeg_mii(arr_int)

        # check the packet number
        tmp_pkg_num = bytearray(2)
        tmp_pkg_num[0] = arr[810]
        tmp_pkg_num[1] = arr[811]

        tmp_pkg = struct.unpack('<H', tmp_pkg_num)[0]
        # print("pkg_num = "+str(tmp_pkg))
        diff_pkg_num = tmp_pkg - self.last_pkn
        if (diff_pkg_num)>1:
            print('packet loss: '+str(diff_pkg_num))
        self.last_pkn = tmp_pkg

        # check some number
        # for i in range(10):
        #     print(arr_int[i])

    def new_data_pkg_binary_bci32(self,arr):

        if (len(arr))!=1086:
            print('something wrong, len is :'+str(len(arr)))
            return

        # arr_int = np.zeros((10*3*9))
        for i in range(10):
            offset_pkg = self.PKG_DATA_OFFSET +i*3*9*self.CH_NUM

            arr_int =  np.zeros((self.CH_NUM*8),dtype = np.int32) # one sample point,with 24 channels 

            for chip_n in range(self.CH_NUM):
                offset_pkg_chip = offset_pkg + chip_n*3*9
                for ch in range(1,9): # ignore the 24 status bits
                    tmp = bytearray(4)
                    for t in range(3):
                        tmp[t+1] = arr[offset_pkg_chip+ch*3+t]
                    if tmp[1] & 0x80:
                        tmp[0] = 0xFF
                    else:
                        tmp[0] = 0x00

                    arr_int[chip_n*8+ch-1] = struct.unpack('>i', tmp)[0]
                    # arr_int[i*27+chip_n*9+ch] = struct.unpack('>i', tmp)[0]

            mLSL.send_bci32(arr_int)

        # check the packet number
        tmp_pkg_num = bytearray(2)
        tmp_pkg_num[0] = arr[2]
        tmp_pkg_num[1] = arr[3]

        tmp_pkg = struct.unpack('<H', tmp_pkg_num)[0]
        # print("pkg_num = "+str(tmp_pkg))
        diff_pkg_num = tmp_pkg - self.last_pkn
        if (diff_pkg_num)>1:
            print('packet loss: '+str(diff_pkg_num))
        self.last_pkn = tmp_pkg


mDP = DATAPKG('dummy')

class MyUDPHandler(socketserver.BaseRequestHandler):

    def handle(self):
        # arr = self.request[0].strip()
        # mDP.new_data_pkg_json(arr)
        # mDP.new_data_pkg_binary(self.request[0])

        # socket = self.request[1]
        # print("{} wrote:".format(self.client_address[0]))
        print(1)
        mDP.new_data_pkg_binary_bci32(self.request[0])


if __name__ == "__main__":
    host_ip = socket.gethostbyname(socket.gethostname())
    print(host_ip)
    # HOST, PORT = , 8081

    with socketserver.ThreadingUDPServer((host_ip, PORT), MyUDPHandler) as server:
        server.serve_forever()














